if(!require("knitr")){
install.packages("knitr")
library(knitr)
}
knitr::opts_chunk$set(echo = TRUE, fig.width=20)
N’OUBLIEZ PAS DE RENSEIGNER LE NOM DE L’OEUVRE
if(!require("knitr")){
install.packages("knitr")
library(knitr)
}
knitr::opts_chunk$set(echo = TRUE, fig.width=20)
Il va falloire télécharger le package UDpipe. Pour le français du XVIIème s. nous conseillons french-gsd, même s’il est (très) loin d’être parfait.
setwd("~/GitHub/Cours_2020_UniGE/Cours_Geneve_13")
Vous pouvez ici rentrer le nom du texte que nous allons étudier. Le nom que vous allez mettre va être reproduit sur tous les graphiques: attention! Enter the name of the text that will be studied (it is the one that will be printed on all the graphs produced here), and the name of the file
if (!require("udpipe")) install.packages("udpipe")
library(udpipe)
Nous allons lemamtiser le texte à l’aide dun modèle UDPipe. Il est en effet plus facile de travailler sur des lemmes pour diminuer la taille du lexique.
Si vous n’avez pas de modèles (il y en a un dans le dossier), vous pouvez les télécharger à cet endroit.
If you do not have an udpipe model, you can download one here (and adjust infra the name)
text_title <- "Boyer - Agamemnon (1680)"
file_name<- "BOYER_AGAMEMNON_1680/BOYER_AGAMEMNON_1680.txt"
#Il pesut être utile de créer un dossier spécifique, pour mettre toutes les images produites dans cet endroit
folder_name <-"BOYER_AGAMEMNON_1680/"
Nous pouvons désormais charger le texte, et le modèle.
#m<-udpipe_download_model(language = "french-gsd")
#m<-udpipe_download_model(language = "french-partut")
#m<-udpipe_download_model(language = "french-sequoia")
udpipe_model_french <- udpipe_load_model(file = "tools/french-gsd-ud-2.4-190531.udpipe")
text_to_lemmatise <- readLines(file_name)
#variable pour les sauvegardes
#nom de fichier sans extension
file_name_noExt <- tools::file_path_sans_ext(file_name)
#ajout d'une extention
filename <- paste(file_name_noExt,"_LEM.txt", sep="")
Je sauvegarde le texte
#on transforme le texte en une longue chaîne de caractères séparés par des espaces.
text_to_lemmatise <- paste(text_to_lemmatise, collapse = " ")
# on lemmatise cette chaîne
x <- udpipe_annotate(udpipe_model_french, x = text_to_lemmatise)
#je fais un data.frame
x <- as.data.frame(x)
# voir un extrait
str(x)
'data.frame': 17093 obs. of 14 variables:
$ doc_id : chr "doc1" "doc1" "doc1" "doc1" ...
$ paragraph_id : int 1 1 1 1 1 1 1 1 1 1 ...
$ sentence_id : int 1 1 1 1 1 1 1 1 1 1 ...
$ sentence : chr "oui, pylade, il est vrai, la valeur et l'adresse ont de l'asie enfin fait triompher la grèce." "oui, pylade, il est vrai, la valeur et l'adresse ont de l'asie enfin fait triompher la grèce." "oui, pylade, il est vrai, la valeur et l'adresse ont de l'asie enfin fait triompher la grèce." "oui, pylade, il est vrai, la valeur et l'adresse ont de l'asie enfin fait triompher la grèce." ...
$ token_id : chr "1" "2" "3" "4" ...
$ token : chr "oui" "," "pylade" "," ...
$ lemma : chr "oui" "," "pylade" "," ...
$ upos : chr "INTJ" "PUNCT" "NOUN" "PUNCT" ...
$ xpos : chr NA NA NA NA ...
$ feats : chr NA NA "Gender=Fem|Number=Sing" NA ...
$ head_token_id: chr "14" "1" "7" "3" ...
$ dep_rel : chr "advmod" "punct" "obl:mod" "punct" ...
$ deps : chr NA NA NA NA ...
$ misc : chr "SpacesBefore=\\s\\s\\s\\s\\s\\s\\t|SpaceAfter=No" NA "SpaceAfter=No" NA ...
cat(x$lemma[1], "", file = filename)
for(i in 2:length(x$token_id)){
if(x$sentence_id[i] != x$sentence_id[i-1])
cat("\n", file = filename, append = T)
if(is.na(x$lemma[i]))
next
cat(x$lemma[i], "", file = filename, append = T)
}
Amine Abdaoui, Jérôme Azé, Sandra Bringay et Pascal Poncelet. “FEEL: French Expanded Emotion Lexicon. Language Resources and Evaluation”, LRE 2016, pp 1-23. Cf. http://www.lirmm.fr/~abdaoui/FEEL
Cf. aussi the package R rfeel: https://github.com/ColinFay/rfeel
if (!require("syuzhet")) install.packages("syuzhet")
library(syuzhet)
On peut jeter un petit coup d’œil à ces lexiques
FEEL = read.csv("lexicons/FEEL-1_clean.csv")
load("lexicons/sentiments_polarity.rda")
load("lexicons/sentiments_score.rda")
Il faut désormais importer le texte que nous allons étudier
View(FEEL)
View(sentiments_polarity)
View(sentiments_score)
Nous utilisons la méthode de Bing pour étudier la polarité: chaque token est comparé à un lexique, où des mots sont catégorés comme positifs ou négatifs.
text_to_analyse <- readLines(filename)
head(text_to_analyse)
[1] "oui , pylade , il être vrai , le valeur et le adresse avoir de le asie enfin faire triompher le grèce . "
[2] "de tout côté en foule on venir dans ce cour , croire de agamemnon célébrer le retour , et toi-même suivant le zèle qui ter guide , pour voler dans mycène avoir quitter le phocide . "
[3] "cependant cher ami , son soin être superflure . "
[4] "le troyen être venger : son père ne vivre plus . "
[5] "il ne être plus ! "
[6] "ô disgrâce à jamais déplorable ! "
Nous pouvons donc désormais proposer une première visualisation
text_to_analyse_bing_vector <- get_sentiment(text_to_analyse, method = "bing", lexicon = FEEL)
head(text_to_analyse_bing_vector, 300)
#summary(text_to_analyse_bing_vector)
Nous avons besoin de normaliser la longueur de notre image pour pouvoir comparer des textes de longueurs différentes. On peut aussi diminuer la taille des chunks pour amplifier les tendances.
Avec une base 100
simple_plot(text_to_analyse_bing_vector, title = paste(text_title, " - BING"))
# on sauvegarde l'image
png(paste(file_name_noExt,"_BING.png", sep=""), height = 900, width = 1600, res = 100)
simple_plot(text_to_analyse_bing_vector, title = paste(text_title, " - BING"))
dev.off()
Avec une base 10
percent_vals <- get_percentage_values(text_to_analyse_bing_vector, bins = 100)
plot(
percent_vals,
type="l",
main=paste(text_title,"base 100", sep=" "),
xlab = "Narrative Time",
ylab= "Emotional Valence",
col="red"
)
#Saving the graph
png(paste(file_name_noExt,"_BASE100.png"), height = 900, width = 1600, res = 100)
plot(
percent_vals,
type="l",
main=paste(text_title,"base 100", sep=" "),
xlab = "Narrative Time",
ylab= "Emotional Valence",
col="red"
)
dev.off()
Avec une base 2
percent_vals <- get_percentage_values(text_to_analyse_bing_vector, bins = 10)
plot(
percent_vals,
type="l",
main=paste(text_title,"base 10", sep=" "),
xlab = "Narrative Time",
ylab= "Emotional Valence",
col="red"
)
#Saving the graph
png(paste(file_name_noExt,"_BASE10.png"), height = 900, width = 1600, res = 100)
plot(
percent_vals,
type="l",
main=paste(text_title,"base 100", sep=" "),
xlab = "Narrative Time",
ylab= "Emotional Valence",
col="red"
)
dev.off()
On peut obtenir une tendance générale avec summary
percent_vals <- get_percentage_values(text_to_analyse_bing_vector, bins = 2)
plot(
percent_vals,
type="l",
main=paste(text_title,"base 2", sep=" "),
xlab = "Narrative Time",
ylab= "Emotional Valence",
col="red"
)
#Saving the graph
png(paste(file_name_noExt,"_BASE2.png"), height = 900, width = 1600, res = 100)
plot(
percent_vals,
type="l",
main=paste(text_title,"base 2", sep=" "),
xlab = "Narrative Time",
ylab= "Emotional Valence",
col="red"
)
dev.off()
quartz_off_screen
2
Pour étudier la joie, nous sortons la colonne joie du lexique pour créer un petit sous-lexique
sum(text_to_analyse_bing_vector)
[1] -232
summary(text_to_analyse_bing_vector)
Min. 1st Qu. Median Mean 3rd Qu. Max.
-3.0000 -1.0000 0.0000 -0.2375 0.0000 2.0000
Je reproduis là même manipulation que supra
custom_dict_joy <- data.frame(word=FEEL$word, value=FEEL$joy)
head(custom_dict_joy)
Qu’est-ce qu’il y a sous le capot
100% center
nous allons regarder les mots qui ont été utilisés pendant l’analyse, classés par fréquence
text_to_analyse_vector_joy <- get_sentiment(text_to_analyse, method = "custom", lexicon = custom_dict_joy)
simple_plot(text_to_analyse_vector_joy, title = paste(text_title, "Joy", sep=" - "))
#Saving the graph
png(paste(file_name_noExt,"_JOY.png"), height = 900, width = 1600, res = 100)
simple_plot(text_to_analyse_vector_joy, title = paste(text_title, "Joy", sep=" - "))
dev.off()
quartz_off_screen
2
Je peux extraire tous les mots utiles pour l’analye
text_to_analyse_tokenised <- table(unlist(strsplit(text_to_analyse, "\\W")))
head(sort(text_to_analyse_tokenised, decreasing = T), n=50)
le de son il que et ce un à être avoir lui
4700 1063 814 794 416 398 333 324 299 293 250 206 171
vous tout je ne en pour dans se quel mais si faire par
163 153 149 144 138 137 123 108 104 97 97 96 83
plus soi cassandre qui dieu fils me aller voir trop amour pouvoir on
80 80 74 73 64 64 62 61 61 57 56 56 55
seigneur ah sur vouloir elle roi oeil coeur devoir père hymen
55 54 54 54 53 49 45 44 44 43 39
Regardons les mots qui sont catégorisés comme de la joie d’aprps FEEL
positive_words=character()
positive_words_custom=character()
for(i in 1:length(text_to_analyse_tokenised)){
# identify positive words
if(get_sentiment(names(text_to_analyse_tokenised[i]), method = "custom", lexicon = custom_dict_joy) > 0){
positive_words = c(positive_words, names(text_to_analyse_tokenised[i]))
positive_words_custom = c(positive_words_custom, (text_to_analyse_tokenised[i]*get_sentiment(names(text_to_analyse_tokenised[i]), method = "custom", lexicon = custom_dict_joy)))
}
}
head(sort(positive_words_custom, decreasing = T), n=50)
triomphe offrir songer enfant premier repos triompher auguste obtenir
"8" "7" "6" "5" "5" "5" "5" "4" "4"
victorieux bien bonheur combler douceur favorable mutin rappeler enfance
"4" "34" "3" "3" "3" "3" "3" "3" "2"
libre reprendre satisfaire superbe survivre joie heureux fille vaincre
"2" "2" "2" "2" "2" "13" "11" "10" "10"
vie amoureux avancer avantageux flatteur gagner heureusement silence songe
"10" "1" "1" "1" "1" "1" "1" "1" "1"
tranquillement
"1"
Le lexique est (vraiment) loin d’êtr parfait: des mots comme content ou fier ne sont pas considéré comme relevant de la joie!
head(FEEL$word[which(FEEL$joy==1)], n=50)
[1] avantageux batifoler bénigne bien bienheureux capiteux chanceux
[8] clément comique commode communicatif consolateur conte convenance
[15] décontracter délice délicieux divertir duveteux éclat existence
[22] faisable favorable ferveur festin festif flatteur folle|fou de joie
[29] fructueux futé gazouillis gemme heureux inventif jovial
[36] joyeusement libidineux lucratif lumineux luxueux majesté miséricordieux
[43] nonchalamment nonchalant officiant opportun pétillement plein été précieux
[50] premier
14126 Levels: ?cuménique ?il ?illet ?uf ?uf de poisson ?uvre ?uvre classique @card@ kilo à base de plante à bord à capuche ... zut
Et donc la phrase “je suis heureux, content et fier” (ou plutôt je être heureux, content et fier) a un score de 1.
FEEL$joy[which(FEEL$word=="joie")]
[1] 1
FEEL$joy[which(FEEL$word=="heureux")]
[1] 1
FEEL$joy[which(FEEL$word=="content")]
[1] 0
FEEL$joy[which(FEEL$word=="fier")]
[1] 0
Je peux recommencer la même étude, mais cette fois avec le lexique de la peur
#je rentre mon texte
text_to_analyse_test <-"je suis heureux, content et fier"
#Je tokenise
text_to_analyse_tokenised_test <- table(unlist(strsplit(text_to_analyse_test, "\\W")))
#Je remets mes variables à zero
positive_words=character()
positive_words_custom=character()
#Je cherche dans le lexique
#Pour chaque mot de ma phrase
for(i in 1:length(text_to_analyse_tokenised_test)){
# si un mot a une valeur supérieure à zéro dans mon lexique
if(get_sentiment(names(text_to_analyse_tokenised_test[i]), method = "custom", lexicon = custom_dict_joy) > 0){
#Je l'ajoute aux mots positifs
positive_words = c(positive_words, names(text_to_analyse_tokenised_test[i]))
positive_words_custom = c(positive_words_custom, (text_to_analyse_tokenised_test[i]*get_sentiment(names(text_to_analyse_tokenised_test[i]), method = "custom", lexicon = custom_dict_joy)))
}
}
positive_words_custom
heureux
"1"
Et donc reprodurie une même visualisation à partir de ce nouveau sous-lexique
custom_dict_fear <- data.frame(word=FEEL$word, value=FEEL$fear)
Extraire les mots utilisés pour l’analyse
#{r, fig.width=6, fig.height=, dpi=10}
text_to_analyse_vector_fear <- get_sentiment(text_to_analyse, method = "custom", lexicon = custom_dict_fear)
simple_plot(text_to_analyse_vector_fear, title = paste(text_title, "Fear", sep=" - "))
#Saving the graph
png(paste(file_name_noExt,"_FEAR.png"), height = 900, width = 1600, res = 100)
simple_plot(text_to_analyse_vector_fear, title = paste(text_title, "Fear", sep=" - "))
dev.off()
quartz_off_screen
2
`
Un grand merci à Simone Rebora (Università di Verona/DHLab Basel) pour son aide.